﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Office.Tools.Ribbon;
using Microsoft.TeamFoundation.Server;
using Microsoft.TeamFoundation.WorkItemTracking.Client;
using Microsoft.TeamFoundation.Client;
using System.Collections;
using System.Windows.Forms;
using System.ComponentModel;
using WordTemplate1.Formulaire;

namespace WordTemplate1
{
    /// <summary>
    ///  Gestion de la connexion à TFS
    /// </summary>
    public class TFS
    {
        internal static TfsTeamProjectCollection tfsTP = null;
        internal static TeamProjectPicker dp;
        internal static ProjectInfo project = null;
        internal static string projectName = null;

        internal WorkItemCollection workItems = null;
        internal List<QueryItem> choices = new List<QueryItem>();
        internal QueryItem Query = null;

        public TFS()
        {

        }

        /// <summary>
        /// Permet d'actualiser les WI
        /// </summary>
        public void ActualiserWI(bool actualise = false, QueryItem query = null)
        {
            Query = query;

            if (actualise)
            {
                    GetQuery();

                    Globals.ThisDocument.taskPanel.ListeQuery = choices;


                    ExecuteQuery(Query);

                    Globals.ThisDocument.taskPanel.trvWI.Nodes.Clear();
                    Globals.ThisDocument.taskPanel.ListWorkItem = workItems;
            }
            else
            {
                if (Globals.ThisDocument.ReadDocumentProperty("TFS") == null)
                {
                    // Ouverture de la fenêtre de sélection des projets dans TFS
                    dp = new TeamProjectPicker();
                    DialogResult dr = dp.ShowDialog();

                    if (dr == DialogResult.OK)
                    {
                        if (dp.SelectedTeamProjectCollection != null)
                        {
                            try
                            {
                                // Récupération du team project collection
                                tfsTP = dp.SelectedTeamProjectCollection;
                            }
                            catch (Exception ex)
                            {
                                tfsTP = null;
                                MessageBox.Show(ex.Message);
                            }

                            if (tfsTP != null)
                            {
                                // Enregistrament dans les paramètres du document
                                Globals.ThisDocument.AddProperties("TFS", dp.SelectedTeamProjectCollection.Uri.ToString(), true);

                                if (dp.SelectedProjects.Count() > 0)
                                {
                                    project = dp.SelectedProjects[0];

                                    Globals.ThisDocument.AddProperties("Project", project.Name, true);


                                    Connexion();
                                    GetQuery();

                                    Globals.ThisDocument.taskPanel.ListeQuery = choices;


                                    ExecuteQuery(Query);

                                    Globals.ThisDocument.taskPanel.trvWI.Nodes.Clear();
                                    Globals.ThisDocument.taskPanel.ListWorkItem = workItems;
                                }
                            }
                        }
                    }
                }
                else
                {
                    try
                    {
                        tfsTP = new TfsTeamProjectCollection(new Uri(Globals.ThisDocument.ReadDocumentProperty("TFS")));
                        ICommonStructureService css = (ICommonStructureService)tfsTP.GetService(typeof(ICommonStructureService));

                        ProjectInfo[] projectList = css.ListAllProjects();

                        var LinqResult = from search in projectList
                                         where search.Name == Globals.ThisDocument.ReadDocumentProperty("Project")
                                         select search;

                        project = LinqResult.First();
                    }
                    catch (Exception ex)
                    {
                        MessageBox.Show(ex.Message);
                    }

                    GetQuery();

                    Globals.ThisDocument.taskPanel.ListeQuery = choices;

                    Globals.ThisDocument.taskPanel.cbxQueries.Text = string.Empty;

                    if (Globals.ThisDocument.ReadDocumentProperty("Query") != null)
                    {
                        var LinqResult = (from q in Globals.ThisDocument.taskPanel.ListeQuery
                                          where q.Name == Globals.ThisDocument.ReadDocumentProperty("Query")
                                          select q).FirstOrDefault();

                        if (LinqResult != null)
                        {
                            Globals.ThisDocument.taskPanel.cbxQueries.Text = Globals.ThisDocument.ReadDocumentProperty("Query");

                            ExecuteQuery(LinqResult);
                        }
                        else
                            ExecuteQuery(Query);
                    }
                    else
                    {
                        ExecuteQuery(Query);
                    }



                    Globals.ThisDocument.taskPanel.trvWI.Nodes.Clear();
                    Globals.ThisDocument.taskPanel.ListWorkItem = workItems;

                }

            }

        }

        /// <summary>
        /// Connexion au server TFS
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        void Connexion()
        {
            if (dp.SelectedTeamProjectCollection != null)
            {
                // Récupération du team project collection
                tfsTP = dp.SelectedTeamProjectCollection;

                if (dp.SelectedProjects.Count() > 0)
                {
                    project = dp.SelectedProjects[0];

                }
            }
        }

        List<QueryItem> GetQuery()
        {
            if (tfsTP != null && project != null)
            {
                // get a reference to the work item tracking service
                var workItemStore = tfsTP.GetService<WorkItemStore>();

                try
                {
                    var projectWithQueries =
                            workItemStore.Projects.Cast<Project>().Where(p => p.QueryHierarchy.Count > 0).Where(p => project.Name == p.Name);

                    if (projectWithQueries.Count() > 0)
                    {
                        RenderQueryMenu(projectWithQueries.First().QueryHierarchy, ref choices);
                    }
                }
                catch (Exception ex)
                {
                    MessageBox.Show(ex.Message);
                }

                return choices;
            }
            return null;
        }

        /// <summary>
        /// Permet de récupérer l'ensemble des type de workitem du projet en court
        /// </summary>
        /// <returns></returns>
        public List<WorkItemType> GetWorkitemType()
        {
            if (tfsTP != null && project != null)
            {
                // get a reference to the work item tracking service
                var workItemStore = tfsTP.GetService<WorkItemStore>();

                try
                {

                    var projectWorkItemType =
                            workItemStore.Projects.Cast<Project>().Where(p => project.Name == p.Name);
                    if (projectWorkItemType.Count() > 0)
                        return projectWorkItemType.First().WorkItemTypes.Cast<WorkItemType>().ToList();
                    else
                        return null;
                }
                catch (Exception ex)
                {
                    MessageBox.Show(ex.Message);
                }

            }
            return null;
        }


        /// <summary>
        /// Permet de récupérer l'ensemble des type de workitem du projet en court
        /// </summary>
        /// <returns></returns>
        public void CreateWI(WorkItemType wt)
        {
            if (tfsTP != null && project != null)
            {
                // get a reference to the work item tracking service
                var workItemStore = tfsTP.GetService<WorkItemStore>();

                WorkItem wi = new WorkItem(wt);

                using (CreateWorkitem frm = new CreateWorkitem(wi, true))
                {
                    frm.ShowDialog();
                }
            }
        }

        void RenderQueryMenu(IEnumerable<QueryItem> queries, ref List<QueryItem> choices, int depth = 0)
        {
            foreach (var queryItem in queries)
            {

                if (queryItem is QueryFolder)
                {
                    RenderQueryMenu(queryItem as QueryFolder, ref choices, depth + 1);
                }
                else
                {
                    choices.Add(queryItem);
                }
            }
        }

        /// <summary>
        /// Execution d'une requete WI
        /// </summary>
        public void ExecuteQuery(QueryItem query = null)
        {

            if (tfsTP != null && project != null)
            {

                // get a reference to the work item tracking service
                var workItemStore = tfsTP.GetService<WorkItemStore>();

                string wiqlQuery = "Select [System.ID] from WorkItem WHERE [System.TeamProject] =  '" + project.Name + "' Order by [System.Title]"; ;


                if (query != null)
                {
                    try
                    {
                        workItems = workItemStore.Query(((QueryDefinition)query).QueryText,
                            new Hashtable { { "project", project.Name } });
                    }
                    catch (Exception ex)
                    {
                        MessageBox.Show(ex.Message);
                    }
                }
                else
                {
                    try
                    {
                        // execute the query and retrieve a collection of workitems
                        workItems = workItemStore.Query(wiqlQuery);
                    }
                    catch (Exception ex)
                    {
                        MessageBox.Show(ex.Message);
                    }
                }
            }
        }


        /// <summary>
        /// Execution d'une requete WI
        /// </summary>
        public WorkItem GetWorkitemByID(int ID)
        {
            // Vérifie la présence du workitem dans la liste déjà chargée
            var LinqResult = (from search in Globals.ThisDocument.taskPanel.WorkItems
                              where search.Id == ID
                              select search).FirstOrDefault();

            if (LinqResult != null)
            {
                return LinqResult;
            }
            else
            {
                if (tfsTP != null && project != null)
                {
                    // get a reference to the work item tracking service
                    var workItemStore = tfsTP.GetService<WorkItemStore>();

                    try
                    {
                        return workItemStore.GetWorkItem(ID);
                    }
                    catch (Exception ex)
                    {
                        MessageBox.Show(ex.Message);
                    }
                }

            }
            return null;
        }
    }
}
